﻿/* PN264 - A Parallel H.264 Encoding Utility
 * Copyright © 2009 PN264 Development Team
 *
 * This software is released the terms and conditions of the MIT License,
 * a copy of which can be found in the License.txt file.
 *
 * Contributors:
 * Will 'AnarkiNet' Shelley (AnarkiNet@gmail.com)
 */
using System;
using System.Collections.Generic;

namespace PN264
{
    /// <summary>
    /// Represents a class that processes tasks assigned from a supervisor.
    /// </summary>
    public sealed class Worker : IDisposable
    {
        #region Constructors
        /// <summary>
        /// Initializes a new instance of the <see cref="Worker"/> class.
        /// </summary>
        public Worker()
        {
        }
        ~Worker()
        {
            // Clean up unmanaged-only resources during object finalization.
            this.Dispose(false);
        }
        #endregion
        #region Events
        public event EventHandler<WorkerStatusChangedEventArgs> StatusChanged;
        #endregion
        #region Fields
        private bool isDisposed;
        private bool isWorking;
        private WorkerStatus status;
        private Task currentTask;
        private readonly Queue<Task> tasks = new Queue<Task>();
        #endregion
        #region Methods
        /// <summary>
        /// Disposes the current <see cref="Worker"/>, cleaning up any managed
        /// and unmanaged resources that are used.
        /// </summary>
        public void Dispose()
        {
            this.Dispose(true);
            GC.SuppressFinalize(this);
        }
        private void Dispose(bool disposing)
        {
            if (!this.IsDisposed)
            {
                if (disposing)
                {
                    //Clean up managed objects too.

                    this.StatusChanged = null;
                    this.status = WorkerStatus.ShutDown;
                    this.tasks.Clear();
                    this.currentTask = null;
                }

                this.isDisposed = true;
            }
        }
        /// <summary>
        /// Raises the <see cref="StatusChanged"/> event.
        /// </summary>
        /// <param name="e">Event data for the event.</param>
        private void OnStatusChanged(WorkerStatusChangedEventArgs e)
        {
            if (this.StatusChanged != null)
            {
                this.StatusChanged(this, e);
            }
        }
        public void Start()
        {
            //TODO: Implement worker starting.
        }
        /// <summary>
        /// Shuts down the current <see cref="Worker"/> after completing all queued tasks.
        /// </summary>
        public void Shutdown()
        {
            this.Shutdown(true);
        }
        /// <summary>
        /// Shuts down the current <see cref="Worker"/>, optionally ignoring queued tasks.
        /// </summary>
        /// <param name="processQueue">Whether to complete processing of queued tasks (true) or shut down after the current task (false).</param>
        public void Shutdown(bool processQueue)
        {
            //TODO: Implement worker shutdown.
        }
        #endregion
        #region Properties
        public Task ActiveTask
        {
            get
            {
                return this.currentTask;
            }
        }
        /// <summary>
        /// Gets a value that indicates if the current <see cref="Worker"/>
        /// has been cleaned up.
        /// </summary>
        public bool IsDisposed
        {
            get
            {
                return this.isDisposed;
            }
        }
        public WorkerStatus Status
        {
            get
            {
                return this.status;
            }
            set
            {
                this.status = value;
                this.OnStatusChanged(new WorkerStatusChangedEventArgs(value));
            }
        }
        
        #endregion
    }
}
